#ifndef PLAYBACKBOX_H_
#define PLAYBACKBOX_H_

#include <qtimer.h>
#include <qmutex.h>
#include <qvaluevector.h>
#include <qptrstack.h>
#include <qtextcodec.h>
#include <qmap.h>

#include <mythtv/mythwidgets.h>
#include <mythtv/dialogbox.h>
#include <mythtv/audiooutput.h>
#include <mythtv/mythdbcon.h>
#include <mythtv/uitypes.h>

#include "mainvisual.h"
#include "CharacterProcessor.h"
#include "AudioPlayer.h"

class Output;
class Decoder;
class Metadata;

class TextBox
{
public:
   TextBox()
   {
      Item = 0;
   };

   void Load( MythThemedDialog* parent, const QString& name )
   {
      Item = parent->getUITextType( name );
   }

   void SetText( const QString& text )
   {
      if( Item != 0 )
      {
         Item->SetText( text );
         Item->refresh();
      }
   }

private:
   UITextType* Item;
};

class SelectionInfo
{
public:
   SelectionInfo(){}
   SelectionInfo( SelectionInfo* info )
   {
      Artist = info->Artist;
      Album  = info->Album;
      Title  = info->Title;
      Path   = info->Path;
   }

   QString    Artist;
   QString    Album;
   QString    Title;
   QString    Path;
};

class AudioUIList
{
public:
   AudioUIList( MythThemedDialog& parent, const QString& obj, QValueVector<SelectionInfo>& list );
   ~AudioUIList();

   void ResetList();
   void Refresh();
   void Add( const QString& display, const SelectionInfo& item );
   int GetItems();
   void SetActive( bool active );
   bool IsActive();
   void SetItemCurrent( int item );
   int GetCurrentItem();
   int Count()
   {
      return DisplayList.count();
   }
   SelectionInfo GetCurrent();
   SelectionInfo Get( int index );
   void EnableForcedFont( int row, QString func );

   void LineUp();
   void LineDown();
   void PageUp();
   void PageDown();
   void Display();

protected:
   UIListType*       UIList;

   QValueVector<QString>         DisplayList;
   QValueVector<SelectionInfo>&  ItemList;

   int Current;
   int First;
   bool Active;
};

class PlaybackBoxMusic : public MythThemedDialog, public AudioPlayer::EventInterface
{
   Q_OBJECT

public:

   void AudioPlayer_State( SelectionInfo& track, PLAYER_STATE state );
   void AudioPlayer_Progress( int position, int length );
   void AudioPlayer_Error( QString err );

   //
   // Now featuring a themed constructor ... YAH!!!
   //
   typedef QValueVector<int> IntVector;

   PlaybackBoxMusic
   (
      MythMainWindow *parent,
      QString window_name,
      QString theme_filename,
      const char *name,
      AudioPlayer& player
   );

   ~PlaybackBoxMusic(void);

   void closeEvent(QCloseEvent *);
//   void showEvent(QShowEvent *);
   void keyPressEvent(QKeyEvent *e);

public slots:

   void play();
   void pause();
   void stop();
   void previous();
   void next();
   void visEnable();
   void bannerDisable();
   void resetTimer();
   void toggleFullBlankVisualizer();
   void end();
   void scanForAudio();
   void closePlaylistPopup();
   void KeypressIdle();
   void EditPlaylist();

   // popup menu
   void showMenu();
   void timeout(void);

signals:

   void dummy();   // debugging

private:
   //void paintEvent(QPaintEvent *);

   void wireUpTheme();
   void setTrackOnLCD(Metadata *mdata);
   void bannerEnable(Metadata *mdata);
   void bannerToggle(Metadata *mdata);

   AudioPlayer&      m_AudioPlayer;

   int outputBufferSize;
   int currentTime;
   int maxTime;

   Metadata *curMeta;

   bool isplaying;

   bool menufilters;

   MainVisual *mainvisual;

   QString visual_mode;
   int visual_mode_delay;
   QTimer *visual_mode_timer;
   QTimer *lcd_update_timer;
   QTimer *banner_timer;
   int visualizer_status;

   bool showrating;
   bool vis_is_big;
   bool first_playlist_check;

   enum SearchStateType
   {
      SEARCH_STATE_ARTIST,
      SEARCH_STATE_ALBUM,
      SEARCH_STATE_TRACK,
      SEARCH_STATE_DIRECTORY,
      SEARCH_PLAYLIST
   };

   class SearchEvent
   {
   public:
      SearchStateType   State;
      QString           Display;

      SearchEvent()
      {
         Query = new MSqlQuery(MSqlQuery::InitCon());
      }

      SearchEvent( const SearchEvent& obj )
      {
         Query = new MSqlQuery(MSqlQuery::InitCon());
         State = obj.State;

         Query->prepare( obj.Query->lastQuery() );
         QMap<QString,QVariant> map = obj.Query->boundValues();
         QMap<QString,QVariant>::Iterator it;
         for( it=map.begin(); it!=map.end(); it++ )
         {
            Query->bindValue( it.key(), it.data() );
         }
         Display = obj.Display;
      }

      ~SearchEvent()
      {
         delete Query;
      }

      bool prepare( const QString& str )
      {
         return Query->prepare( str );
      }

      void bindValue( const QString& placeholder, const QString& val )
      {
         Query->bindValue( placeholder, val );
      }

      QVariant boundValue( const QString& placeholder )
      {
         return Query->boundValue( placeholder );
      }

      QString lastQuery()
      {
         return Query->lastQuery();
      }

      bool exec()
      {
         return Query->exec();
      }

      bool isActive()
      {
         return Query->isActive();
      }

      int size()
      {
         return Query->size();
      }

      bool next()
      {
         return Query->next();
      }

      QVariant value( int i )
      {
         return Query->value( i );
      }

      void Show()
      {
         printf( "%s\n", Query->lastQuery().ascii() );
         QMap<QString,QVariant> map = Query->boundValues();
         QMap<QString,QVariant>::Iterator it;
         for( it=map.begin(); it!=map.end(); it++ )
         {
            printf( "Bind %s as %s\n", it.key().ascii(), it.data().asString().ascii() );
         }
      }

   private:

      MSqlQuery*              Query;
   };

   bool ProcessIdleEvent( QString action );
   bool ProcessSearchEvent( QString action );
   bool ProcessPlaylistEvent( QString action );
   void PerformSearch( SearchEvent* search );
   void PerformSelect();
   bool BackOutSelection();

   bool ModifyingPlaylist;

   QPtrStack<SearchEvent> SearchStack;

   SearchEvent*         CurrentSearch;
   CharacterProcessor*  TextTransform;
   QTimer*              KeypressIdleTimer;

   bool keyboard_accelerators;

   MythPopupBox *playlist_popup;

   //
   //  Theme-related "widgets"
   //

   TextBox              playlist_name_text;
   TextBox              playlist_state_text;
   TextBox              current_visualization_text;
   TextBox              selection_state_text;
   TextBox              selection_string_text;
   TextBox              InfoArtist;
   TextBox              InfoAlbum;
   TextBox              InfoTitle;

   TextBox              StatusScan;
   TextBox              StatusPlay;
   TextBox              StatusPlaybackMode;

   AudioUIList*         SelectionListUI;
   AudioUIList*         PlayListUI;
};


#endif
